<template>
  <div
    class="progress-bar"
    @click="onClick"
  >
      <div class="bar-inner">
        <!-- 左侧黄色进度条 -->
          <div
            class="progress"
            ref="progress"
            :style="progressStyle"
          ></div>
          <div
            class="progress-btn-wrapper"
            :style="btnStyle"
            @touchstart.prevent="onTouchStart"
            @touchmove.prevent="onTouchMove"
            @touchend.prevent="onTouchEnd"
          >
              <div class="progress-btn"></div>
          </div>
      </div>
  </div>
</template>

<script>
const progressBtnWidth = 16;

export default {
  name: 'progress-bar',
  // progress-changing 触摸过程中手指还未离开
  // progress-chang 手指离开屏幕触发
  emits: ['progress-changing', 'progress-changed'],
  props: {
    // 进度
    progress: {
      type: Number,
      default: 0
    }
  },
  data() {
    return {
      // 偏移量
      offset: 0
    };
  },
  computed: {
    // 黄色条的宽度
    progressStyle() {
      return `width: ${this.offset}px`;
    },
    btnStyle() {
      return `transform: translate3d(${this.offset}px, 0, 0)`;
    }
  },
  watch: {
    progress(newProgress) {
      this.setOffset(newProgress);
    }
  },
  created() {
    // 不在data中定义是因为这个变量不需要去观测变化,也不需要去映射到模板
    // 定义在data中,一旦发生变化会触发模板的重新渲染,会影响性能
    // offset变化时,模板需要得到重新渲染
    this.touch = {};
  },
  methods: {
    // 重新计算当前播放进度
    setOffset(progress) {
      // 进度条长度
      // 总宽度 - 拖动按钮宽度
      const barWidth = this.$el.clientWidth - progressBtnWidth;
      // 偏移量
      // 进度条长度 * 当前播放进度
      this.offset = barWidth * progress;
    },
    // 进度条点击
    onClick(e) {
      console.log(this.$el.getBoundingClientRect());
      // getBoundingClientRect获得页面中某个元素的左，上，右和下分别相对浏览器视窗的位置
      // rect.left 进度条起始点距离视口左侧的距离
      // offsetWidth 当前点击位置 - 进度条起始点距离视口左侧的距离 = 按钮偏移量
      const rect = this.$el.getBoundingClientRect();
      const offsetWidth = e.pageX - rect.left;
      // 进度条总长度
      const barWidth = this.$el.clientWidth - progressBtnWidth;
      const progress = offsetWidth / barWidth;
      this.$emit('progress-changed', progress);
    },
    // 触摸开始
    onTouchStart(e) {
      // 需要获取到一开始按钮的位置,和左侧进度条的宽度
      // 记录按钮按下位置
      this.touch.x1 = e.touches[0].pageX;
      // 左侧黄色进度条宽度
      this.touch.beginWidth = this.$refs.progress.clientWidth;
    },
    // 触摸过程中
    onTouchMove(e) {
      console.log(e.touches[0].pageX);
      // 需要知道相对于初始位置偏移多少
      // 触摸过程中按钮的最后位置 - 初始位置 = 本次拖动的移动距离
      const delta = e.touches[0].pageX - this.touch.x1;
      // 位移过后进度条最新宽度 = 黄色进度条初始宽度 + 拖动的距离
      const tempWidth = this.touch.beginWidth + delta;
      // 进度条总长度
      const barWidth = this.$el.clientWidth - progressBtnWidth;
      // 最终修改后的值(限定在0 - 1之间)
      const progress = Math.min(1, Math.max(tempWidth / barWidth, 0));
      // 计算偏移量
      this.offset = barWidth * progress;
      this.$emit('progress-changing', progress);
    },
    // 触摸结束
    onTouchEnd() {
      // 进度条总长度
      const barWidth = this.$el.clientWidth - progressBtnWidth;
      // 记录黄条当前宽度
      const progress = this.$refs.progress.clientWidth / barWidth;
      this.$emit('progress-changed', progress);
    }
  }
};
</script>

<style lang="scss" scoped>
.progress-bar {
    height: 30px;
    .bar-inner {
        position: relative;
        top: 13px;
        height: 4px;
        background: rgba(0, 0, 0, 0.3);
        .progress {
          position: absolute;
          height: 100%;
          background: $color-theme;
        }
        .progress-btn-wrapper {
          position: absolute;
          left: -8px;
          top: -13px;
          width: 30px;
          height: 30px;
          .progress-btn {
              position: relative;
              top: 7px;
              left: 7px;
              box-sizing: border-box;
              width: 16px;
              height: 16px;
              border: 3px solid $color-text;
              border-radius: 50%;
              background: $color-theme;
          }
        }
    }
}
</style>
